package com.example.wtt.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.example.wtt.common.AES;
import com.example.wtt.common.Constants;
import com.example.wtt.controller.dto.DynamicDTO;
import com.example.wtt.controller.dto.HomeDTO;
import com.example.wtt.controller.dto.UserDTO;
import com.example.wtt.entity.User;
import com.example.wtt.entity.Validation;
import com.example.wtt.exception.ServiceException;
import com.example.wtt.mapper.UserMapper;
import com.example.wtt.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class UserService extends ServiceImpl<UserMapper, User>{

    @Value("${spring.mail.username}")
    private String from;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private JavaMailSender javaMailSender;
    @Autowired
    private ValidationService validationService;
    private AES aes;

//    登录
    public UserDTO login(UserDTO userDTO) throws Exception {
        userDTO.setEmail(aes.encrypt(userDTO.getEmail().getBytes()).toString());
        userDTO.setPassword(aes.encrypt(userDTO.getPassword().getBytes()).toString());
        User one = getUserInfo(userDTO);
        if(one != null){
            // 将one复制到userDTO中
            BeanUtil.copyProperties(one,userDTO,true);
            String token = TokenUtils.genToken(one.getId().toString(),one.getPassword());
            userDTO.setToken(token);
            // 查询用户的身份
//            String roleFlag = one.getRole();
//            Integer roleId = roleMapper.selectByFlag(roleFlag);
            // 查询用户的菜单权限
//            List<Menu> roleMenus = roleMenuMapper.selectMenus(roleId);

//            userDTO.setRole(roleFlag);
//            userDTO.setMenus(roleMenus);
            userDTO.setEmail(aes.decrypt(userDTO.getEmail().getBytes()).toString());
            userDTO.setPassword(aes.decrypt(userDTO.getPassword().getBytes()).toString());
            return userDTO;
        }else {
            throw new ServiceException(Constants.CODE_600,"用户名或密码法错误");
        }
    }

    public void sendEmailCode(String email) throws Exception {
        Date now = new Date();
        QueryWrapper<Validation> validationQueryWrapper = new QueryWrapper<>();
        validationQueryWrapper.eq("email",aes.encrypt(email.getBytes()));
        Validation validation = validationService.getOne(validationQueryWrapper);
        if(validation == null){
            throw new ServiceException(Constants.CODE_400,"邮箱不存在");
        }
        validationQueryWrapper.eq("type",0);
        validation = validationService.getOne(validationQueryWrapper);
        if (validation == null){
//            邮箱存在，验证码类型不对
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(email);

            message.setSentDate(now);
            String emailCode = RandomUtil.randomNumbers(4);
            message.setSubject(emailCode+"【文图图】验证码");
            message.setText("您本次邮箱登录的验证码为："+emailCode+"，有效期5分钟，请妥善保管验证码，切勿泄漏。");
            javaMailSender.send(message);

            validationService.saveEmailCode(email,emailCode, DateUtil.offsetMinute(now,5), 0);
        } else {
            validationQueryWrapper.ge("time",now);
            validation = validationService.getOne(validationQueryWrapper);
            if(validation != null){
                throw new ServiceException(Constants.CODE_600,"当前您的验证码仍然有效，请不要重复发送");
            }
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom(from);
            message.setTo(email);

            message.setSentDate(now);
            String emailCode = RandomUtil.randomNumbers(4);
            message.setSubject(emailCode+"【文图图】验证码");
            message.setText("您本次邮箱登录的验证码为："+emailCode+"，有效期5分钟，请妥善保管验证码，切勿泄漏。");
            javaMailSender.send(message);

            validationService.saveEmailCode(email,emailCode, DateUtil.offsetMinute(now,5), 0);
        }
    }

//    注册时的邮箱发送
    public void rSendEmailCode(Validation validation) throws Exception {
        Date now = new Date();
        String email = validation.getEmail();

        QueryWrapper<Validation> validationQueryWrapper = new QueryWrapper<>();
        validationQueryWrapper.eq("email",aes.encrypt(email.getBytes()));
        validationQueryWrapper.ge("time",now);
        validationQueryWrapper.eq("type", 1);
        Validation validation1 = validationService.getOne(validationQueryWrapper);
        if(validation1 != null){
            throw new ServiceException(Constants.CODE_600,"当前您的验证码仍然有效，请不要重复发送");
        }
        QueryWrapper<Validation> v = new QueryWrapper<>();
        v.eq("email",aes.encrypt(email.getBytes()));
        v.eq("type", 0);
        validation1 = validationService.getOne(v);
        if(validation1 != null){
            throw new ServiceException(Constants.CODE_600,"邮箱已注册");
        }
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(email);

        message.setSentDate(now);
        String emailCode = RandomUtil.randomNumbers(4);
        message.setSubject(emailCode+"【文图图】验证码");
        message.setText("您本次邮箱登录的验证码为："+emailCode+"，有效期5分钟，请妥善保管验证码，切勿泄漏。");
        javaMailSender.send(message);

        validationService.saveEmailCode(email, emailCode, DateUtil.offsetMinute(now,5), 1);
    }

    public UserDTO loginEmail(UserDTO userDTO) throws Exception {
        String email = userDTO.getEmail();
        String code = userDTO.getEmailCode();
        //先查询邮箱验证的表，查看之前有没有发送过验证码，如果不存在就重新获取
        QueryWrapper<Validation> validationQueryWrapper = new QueryWrapper<>();
        validationQueryWrapper.eq("email", aes.encrypt(email.getBytes()));
        validationQueryWrapper.eq("code",code);
        validationQueryWrapper.ge("time", new Date());
        validationQueryWrapper.eq("type", 0);
        Validation one = validationService.getOne(validationQueryWrapper);

        if(one == null){
            throw new ServiceException(Constants.CODE_600, "验证码过期，请重新获取");
        }

        //如果验证通过了，就查询用户信息
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("email", aes.encrypt(email.getBytes()));
        User user = getOne(userQueryWrapper);

        if(user == null){
            throw new ServiceException(Constants.CODE_600, "未找到用户");
        }

        BeanUtil.copyProperties(user, userDTO, true);

        // 设置token
        String token = TokenUtils.genToken(user.getId().toString(),user.getPassword());
        userDTO.setToken(token);
        // 查询用户的身份
//        String roleFlag = user.getRole();
//        Integer roleId = roleMapper.selectByFlag(roleFlag);
        // 查询用户的菜单权限
//        List<Menu> roleMenus = roleMenuMapper.selectMenus(roleId);
//
//        userDTO.setRole(roleFlag);
//        userDTO.setMenus(roleMenus);
        return userDTO;
    }
    public User register(UserDTO userDTO) throws Exception {
        userDTO.setPassword(aes.encrypt(userDTO.getPassword().getBytes()).toString());
        userDTO.setEmail(aes.encrypt(userDTO.getEmail().getBytes()).toString());
//        检查用户是否存在
        User one = getUserInfoE(userDTO);
        if(one == null){
            System.out.println(userDTO);
            one = new User();
            BeanUtil.copyProperties(userDTO,one,true);
            System.out.println(userDTO);
            save(one);
        } else {
            throw new ServiceException(Constants.CODE_600, "用户名已存在");
        }
//        检查验证码是否过期
        String email = userDTO.getEmail();
        String code = userDTO.getEmailCode();
        QueryWrapper<Validation> validationQueryWrapper = new QueryWrapper<>();
        validationQueryWrapper.eq("email", email);
        validationQueryWrapper.eq("code",code);
        validationQueryWrapper.ge("time", new Date());
        validationQueryWrapper.eq("type", 1);
        Validation v = validationService.getOne(validationQueryWrapper);

        if(v == null){
            throw new ServiceException(Constants.CODE_600, "验证码过期，请重新获取");
        }

        one.setPassword(aes.decrypt(one.getPassword().getBytes()).toString());
        one.setEmail(aes.decrypt(one.getEmail().getBytes()).toString());
        return one;
    }

    private User getUserInfo(UserDTO userDTO) throws Exception {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", userDTO.getUsername());
        queryWrapper.eq("password", userDTO.getPassword());

        User one = getOne(queryWrapper);

        one.setPassword(aes.decrypt(one.getPassword().getBytes()).toString());
        one.setEmail(aes.decrypt(one.getEmail().getBytes()).toString());

        return one;
    }

    private User getUserInfoE(UserDTO userDTO) throws Exception {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", aes.encrypt(userDTO.getEmail().getBytes()));
        User one = getOne(queryWrapper);
        one.setPassword(aes.decrypt(one.getPassword().getBytes()).toString());
        one.setEmail(aes.decrypt(one.getEmail().getBytes()).toString());
        return one;
    }

    public List<DynamicDTO> findHome() {
        return userMapper.findHome();
    }

    public List<DynamicDTO> dynamicCollect(Integer userId) {
        return userMapper.dynamicCollect(userId);
    }

    public Integer becomeVip(Integer userId) {
        return userMapper.becomeVip(userId);
    }

//    public Integer warn(Integer id) {
//        return userMapper.warn(id);
//    }
//
//    public Integer recharge(Object object) {
//        return userMapper.recharge(object);
//    }


}
